from solvers.formtest.formtestbase import FormTestBase
from dolfin import *

#NO PER PARTES----------------------------------------------------------------------------------------------
class F1_1(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx + dt*inner(v,nabla_grad(phi))*varphi*dx

class F1_2(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx + dt*nabla_div(phi*v)*varphi*dx

class F1_3(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx + 0.5*dt*inner(v,nabla_grad(phi))*varphi*dx + 0.5*dt*nabla_div(phi*v)*varphi*dx
#PER PARTES, NO BC--------------------------------------------------------------------------------------------------------------------------
class F2_1(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx + dt*phi*varphi*inner(v,n)*ds - dt*inner(v,nabla_grad(varphi))*phi*dx

class F2_2(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx + dt*phi*varphi*inner(v,n)*ds - dt*nabla_div(v*varphi)*phi*dx

class F2_3(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx + dt*phi*varphi*inner(v,n)*ds\
               -0.5*dt*inner(v,nabla_grad(varphi))*phi*dx -0.5*dt*nabla_div(v*varphi)*phi*dx
#PER PARTES, 0 ON SURFACE WEAKLY---------------------------------------------------------------------------------------------
class F3_1(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx - dt*inner(v,nabla_grad(varphi))*phi*dx

class F3_2(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx - dt*nabla_div(v*varphi)*phi*dx

class F3_3(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx -0.5*dt*inner(v,nabla_grad(varphi))*phi*dx -0.5*dt*nabla_div(v*varphi)*phi*dx
#NO PER PARTES FOR CONVECTIVE TERM, PER PARTES DIFFUSUSIVE TERM-NO BC----------------------------------------------------------------------
class F4_1(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx + dt*inner(v,nabla_grad(phi))*varphi*dx\
               -eps*dt*varphi*inner(nabla_grad(phi),n)*ds + eps*dt*inner(nabla_grad(phi),nabla_grad(varphi))*dx

class F4_2(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx + dt*nabla_div(phi*v)*varphi*dx\
               -eps*dt*varphi*inner(nabla_grad(phi),n)*ds + eps*dt*inner(nabla_grad(phi),nabla_grad(varphi))*dx

class F4_3(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx + 0.5*dt*inner(v,nabla_grad(phi))*varphi*dx + 0.5*dt*nabla_div(phi*v)*varphi*dx\
               -eps*dt*varphi*inner(nabla_grad(phi),n)*ds + eps*dt*inner(nabla_grad(phi),nabla_grad(varphi))*dx
#NO PER PARTES FOR CONVECTIVE TERM, PER PARTES DIFFUSUSIVE TERM - 0 surface term--------------------------------------------------
class F5_1(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx + dt*inner(v,nabla_grad(phi))*varphi*dx\
               + eps*dt*inner(nabla_grad(phi),nabla_grad(varphi))*dx

class F5_2(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx + dt*nabla_div(phi*v)*varphi*dx\
               + eps*dt*inner(nabla_grad(phi),nabla_grad(varphi))*dx

class F5_3(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx + 0.5*dt*inner(v,nabla_grad(phi))*varphi*dx + 0.5*dt*nabla_div(phi*v)*varphi*dx\
               + eps*dt*inner(nabla_grad(phi),nabla_grad(varphi))*dx
#NO PER PARTES FOR CONVECTIVE TERM, NO PER PARTES DIFFUSUSIVE TERM--------------------------------------------------
class F6_1(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx + dt*inner(v,nabla_grad(phi))*varphi*dx - eps*dt*nabla_div(nabla_grad(phi))*varphi*dx

class F6_2(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx + dt*nabla_div(phi*v)*varphi*dx - eps*dt*nabla_div(nabla_grad(phi))*varphi*dx

class F6_3(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx + 0.5*dt*inner(v,nabla_grad(phi))*varphi*dx + 0.5*dt*nabla_div(phi*v)*varphi*dx\
                - eps*dt*nabla_div(nabla_grad(phi))*varphi*dx
#PER PARTES CONVECTIVE-NO BC, NO PER PARTES DIFFUSIVE------------------------------------------------------------------------------------
class F7_1(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx + dt*phi*varphi*inner(v,n)*ds - dt*inner(v,nabla_grad(varphi))*phi*dx\
               - eps*dt*nabla_div(nabla_grad(phi))*varphi*dx

class F7_2(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx + dt*phi*varphi*inner(v,n)*ds - dt*nabla_div(v*varphi)*phi*dx\
               - eps*dt*nabla_div(nabla_grad(phi))*varphi*dx

class F7_3(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx + dt*phi*varphi*inner(v,n)*ds\
               -0.5*dt*inner(v,nabla_grad(varphi))*phi*dx -0.5*dt*nabla_div(v*varphi)*phi*dx\
               - eps*dt*nabla_div(nabla_grad(phi))*varphi*dx
#PER PARTES CONVECTIVE-0 WEAKLY ON SURFACE, NO PER PARTES DIFFUSIVE----------------------------------------------------------------------
class F8_1(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx - dt*inner(v,nabla_grad(varphi))*phi*dx\
               - eps*dt*nabla_div(nabla_grad(phi))*varphi*dx

class F8_2(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx - dt*nabla_div(v*varphi)*phi*dx\
               - eps*dt*nabla_div(nabla_grad(phi))*varphi*dx

class F8_3(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx\
               -0.5*dt*inner(v,nabla_grad(varphi))*phi*dx -0.5*dt*nabla_div(v*varphi)*phi*dx\
               - eps*dt*nabla_div(nabla_grad(phi))*varphi*dx
#PER PERTES CONV - NO BC, PER PARTES DIFF - NO BC-----------------------------------------------------------
class F9_1(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx + dt*phi*varphi*inner(v,n)*ds - dt*inner(v,nabla_grad(varphi))*phi*dx\
               -eps*dt*varphi*inner(nabla_grad(phi),n)*ds + eps*dt*inner(nabla_grad(phi),nabla_grad(varphi))*dx

class F9_2(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx + dt*phi*varphi*inner(v,n)*ds - dt*nabla_div(v*varphi)*phi*dx\
               -eps*dt*varphi*inner(nabla_grad(phi),n)*ds + eps*dt*inner(nabla_grad(phi),nabla_grad(varphi))*dx

class F9_3(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx + dt*phi*varphi*inner(v,n)*ds\
               -0.5*dt*inner(v,nabla_grad(varphi))*phi*dx -0.5*dt*nabla_div(v*varphi)*phi*dx\
               -eps*dt*varphi*inner(nabla_grad(phi),n)*ds + eps*dt*inner(nabla_grad(phi),nabla_grad(varphi))*dx
#PER PERTES CONV - NO BC, PER PARTES DIFF - NO BC-----------------------------------------------------------
class F10_1(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx - dt*inner(v,nabla_grad(varphi))*phi*dx\
               -eps*dt*varphi*inner(nabla_grad(phi),n)*ds + eps*dt*inner(nabla_grad(phi),nabla_grad(varphi))*dx

class F10_2(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx - dt*nabla_div(v*varphi)*phi*dx\
               -eps*dt*varphi*inner(nabla_grad(phi),n)*ds + eps*dt*inner(nabla_grad(phi),nabla_grad(varphi))*dx

class F10_3(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx\
               -0.5*dt*inner(v,nabla_grad(varphi))*phi*dx -0.5*dt*nabla_div(v*varphi)*phi*dx\
               -eps*dt*varphi*inner(nabla_grad(phi),n)*ds + eps*dt*inner(nabla_grad(phi),nabla_grad(varphi))*dx
#PER PERTES CONV - NO BC, PER PARTES DIFF - 0 SURFACE TERM-------------------------------------------------------
class F11_1(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx + dt*phi*varphi*inner(v,n)*ds - dt*inner(v,nabla_grad(varphi))*phi*dx\
               + eps*dt*inner(nabla_grad(phi),nabla_grad(varphi))*dx

class F11_2(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx + dt*phi*varphi*inner(v,n)*ds - dt*nabla_div(v*varphi)*phi*dx\
               + eps*dt*inner(nabla_grad(phi),nabla_grad(varphi))*dx

class F11_3(FormTestBase):
    def __init__(self):
        FormTestBase.__init__(self)
        self.methodDir += self.__class__.__name__

    def __call__(self,phi,phi_,varphi,v,n,dt,eps=0.01):
        return phi*varphi*dx - phi_*varphi*dx + dt*phi*varphi*inner(v,n)*ds\
               -0.5*dt*inner(v,nabla_grad(varphi))*phi*dx -0.5*dt*nabla_div(v*varphi)*phi*dx\
               + eps*dt*inner(nabla_grad(phi),nabla_grad(varphi))*dx

allForms = [F1_1(),F1_2(),F1_3(),\
            F2_1(),F2_2(),F2_3(),\
            F3_1(),F3_2(),F3_3(),\
            F4_1(),F4_2(),F4_3(),\
            F5_1(),F5_2(),F5_3(),\
            F6_1(),F6_2(),F6_3(),\
            F7_1(),F7_2(),F7_3(),\
            F8_1(),F8_2(),F8_3(),\
            F9_1(),F9_2(),F9_3(),\
            F10_1(),F10_2(),F10_3(),\
            F11_1(),F11_2(),F11_3()]
